package epam.car.rent;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.*;

import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;

import epam.car.rent.exceptions.*;

/**
 * For now, Management it's just a class for managing subclasses (see {@link Client}, {@link Car}, {@link Manager}, {@link Order})
 * 
 * Also it's a factory for creating various objects of subclasses.
 * 
 * 
 *  
 * @author Alexander Tretyak
 *
 */
public class Management{
	/**
	 * parsers for various types of file formats
	 * @author Alexander Tretyak
	 *
	 */
	private static class Parsers {
		static ArrayList<String[]> parseTxt(ArrayList<String> toParse) {
			toParse.remove(0);
			ArrayList<String[]> splitted = new ArrayList<String[]>();

			for (String string : toParse) {
				splitted.add(string.split("\\t"));
			}
			return splitted;
		}
		
		static ArrayList<String[]> parseCsv(ArrayList<String> toParse) {
			ArrayList<String[]> splitted = new ArrayList<String[]>();
			toParse.remove(0);
			for (String string : toParse) {
				splitted.add(string.split(";"));
			}
			return splitted;
		}
		
		static ArrayList<String[]> parseJson(ArrayList<String> toParse) {
			ArrayList<String[]> splitted = new ArrayList<String[]>();
			ArrayList<String> strBuff = new ArrayList<String>();
			String buff = new String();
			String regexp = "(\\t++\\s*+\")|(\"\\s*+:\\s++\")|(\",$)";

			for (String string : toParse) {
				if ((!string.equals("}"))&&(!string.equals("{"))){
					string = string.replaceAll(regexp, "_");
					buff += string;
				}else{
					if(!buff.equals("")){
						strBuff.add(buff);
						buff = "";
					}
				}
			}
			for (String string : strBuff) {
				string = string.replaceAll("_++", ";");
				string = string.replaceAll("(^.)|(.$)", "");
				splitted.add(string.split(";"));
			}
			return splitted;
		}
	}
	
	private static ArrayList<Car> cars = new ArrayList<Car>();
	private static ArrayList<Client> clients = new ArrayList<Client>();
	private static ArrayList<Order> orders = new ArrayList<Order>();
	private static ArrayList<Manager> managers = new ArrayList<Manager>();
	
	protected Management() {
	}
	
	private static Random random = new Random();
	
	public static long formId(){
		return Math.abs(random.nextInt(2000));
	}
/**
 * Creates client
 * @param name
 * @param passportId
 * @param money
 * @param password
 * @param email
 * @return
 */
	public static Management create(String name, String passportId, float money, String password, String email) {

		try {
			clients.add(new Client(name, passportId, money, password, email));
			return clients.get(clients.size() - 1);
		} catch (ClientException e) {
			System.out.println(e.getMessage());
			return null;
		}
	}
	
	/**
	 * Creates a car
	 * @param aModel
	 * @param aPrice
	 * @param carType
	 * @return
	 */
	public static Management create(String aModel, double aPrice, String carType) {
			try {
				cars.add(new Car(aModel, aPrice, carType));
				cars.get(cars.size() - 1).setCarId(formId());
				return cars.get(cars.size() - 1);
			} catch (CarException e) {
				System.out.println(e.getMessage());
				return null;
			}
	}
	
	/**
	 * creates an Order
	 * @param m
	 * @param client
	 * @param car
	 * @param creationDate
	 * @return
	 */
	public static Management create(Manager m, Client client, Car car, String creationDate) {
		orders.add(new Order(m, client, car, creationDate));
		return orders.get(orders.size() - 1);
	}
	/**
	 * Creates a Manager
	 * @param name
	 * @param pass
	 * @return
	 */
	public static Management create(String name, String pass) {
		managers.add(new Manager(name,pass));
		return managers.get(managers.size() - 1);
	}

	/**
	 * Returns a writer for different types of file formats (see {@link WriterType})
	 * @param wt
	 * @return
	 */
	public static Writer getWriter(WriterType wt) {
		switch (wt) {
		case TXT:
			return new TextFileWriter();
		case JSON:
			return new TextFileWriter();
		case CSV:
			return new TextFileWriter();
		case XML:
			return new XmlFileWriter();
		default:
			return null;
		}
	}
	
	@Deprecated
	public static Client getClientByPID(String pid) {

		for (Client c : clients) {
			if (c.getPassportId().equals(pid)) {
				return c;
			}
		}
		return null;
	}
	@Deprecated
	public static Order getOrderById(Long id) {
		for (Order o : orders) {
			if (o.getId()==id) {
				return o;
			}
		}
		return null;
	}
	@Deprecated
	public static Car getCarById(long id) {
		for (Car c : cars) {
			if (c.getId() == id) {
				return c;
			}
		}
		return null;
	}
	
	/**
	 * Exports cars to file
	 * @param fileName
	 * @param wt Writer type
	 */
	public static void exportCarsToFile(String fileName, WriterType wt) {
		Writer w = getWriter(wt);
		int i = 0;
		switch(wt){
		case TXT:
			String[] records = new String[cars.size() + 1];
			records[0] = "id\t������ ������\t����\t���\t�����������\t��� ����������\t�� ������� ���� ����������\n";
			i = 1;
			for (Car c : cars) {
				records[i] = c.toString("to file") + "\n";
				i++;
			}
			w.write(fileName, records);
			break;
		case JSON:
			ArrayList<String> jsonRecords = new ArrayList<String>();
			for (Car c : cars) {
				jsonRecords.add("{\n");
				jsonRecords.add("\t\"Car ID\": " + "\"" + c.getId() + "\",\n");
				jsonRecords.add("\t\"Car model\": " + "\"" + c.getModel() + "\",\n");
				jsonRecords.add("\t\"Price\": " + "\"" + c.getPrice() + "\",\n");
				jsonRecords.add("\t\"Car Type\": " + "\"" + c.getCarType() + "\",\n");
				jsonRecords.add("\t\"Damages\": " + "\"" + c.getDamages() + "\",\n");
				jsonRecords.add("\t\"Rent by client (id)\": " + "\"" + c.getRentBy() + "\",\n");
				//jsonRecords.add("\t\"Rent for\": " + "\"" + c.getRentFor() + "\",\n");
				jsonRecords.add("}\n");
			}
			String[] toRec = new String[jsonRecords.size()];
			int j=0;
			for (String string : jsonRecords) {
				toRec[j] = string;
				j++;
			}
			w.write(fileName, toRec);
			break;
		case YAML:
			
			break;
		case CSV:
			String[] csvRecords = new String[cars.size() + 1];
			csvRecords[0] = "id;������ ������;����;���;�����������;��� ����������;�� ������� ���� ����������\n";
			i = 1;
			for (Car c : cars) {
				csvRecords[i] = c.getId()
						+ ";"
						+ c.getModel()
						+ ";"
						+ c.getPrice()
						+ ";"
						+ c.getCarType()
						+ ";"
						+ c.getDamages()
						+ ";"
						+ ((c.getRentBy() != null) ? c.getRentBy()
								.getPassportId() : "") + ";" + "\n";
				i++;
			}
			w.write(fileName, csvRecords);
			break;
		case XML:
			//String[] xmlRecords = new String[cars.size()];
			ArrayList<String> data = new ArrayList<String>();
			data.add("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n");
			data.add("<cars>\n");
			i=0;
			for (Car c : cars) {
				data.add("\t<car>\n");
				data.add("\t\t<car_id>\n"+"\t\t\t"+c.getId()+"\n"
							+"\t\t</car_id>\n"
							+"\t\t<car_rent_by>\n"
							+"\t\t\t"+c.getRentBy()+"\n"
							+"\t\t</car_rent_by>\n"
							+"\t\t<car_model>\n"
							+"\t\t\t"+c.getModel()+"\n"
							+"\t\t</car_model>\n"
							+"\t\t<car_price>\n"
							+"\t\t\t"+c.getPrice()+"\n"
							+"\t\t</car_price>\n"
							+"\t\t<car_type>\n"
							+"\t\t\t"+c.getCarType()+"\n"
							+"\t\t</car_type>\n"
							+"\t\t<car_damages>\n"
							+"\t\t\t"+c.getDamages()+"\n"
							+"\t\t</car_damages>\n");
				data.add("\t</car>\n");
				//System.out.println("added: "+xmlRecords[i]);
				i++;
			}
			data.add("</cars>");
			
			String[] xmlToRec = new String[data.size()];
			i=0;
			for (String string : data) {
				xmlToRec[i] = string;
				i++;
			}
			w.write(fileName, xmlToRec);
			break;
		default:
			break;
		}
	}
	/**
	 * Exports clients to file
	 * @param fileName 
	 * @param wt writer type
	 */
	public static void exportClientsToFile(String fileName, WriterType wt){
		Writer w = getWriter(wt);
		int i=0;
		switch (wt) {
		case TXT:
			String[] records = new String[clients.size() + 1];
			records[0] = "���\t����� ��������\t����� �� �����\t������\tEmail\n";
			i = 1;
			for (Client c : clients) {
				records[i] = c.toString("to file") + "\n";
				i++;
			}
			w.write(fileName, records);
			break;
		case JSON:
			ArrayList<String> jsonRecords = new ArrayList<String>();
			for (Client c : clients) {
				jsonRecords.add("{\n");
				jsonRecords.add("\t\"Name\": " + "\"" + c.getName() + "\",\n");
				jsonRecords.add("\t\"Passport ID\": " + "\"" + c.getPassportId() + "\",\n");
				jsonRecords.add("\t\"Money\": " + "\"" + c.getMoney() + "\",\n");
				jsonRecords.add("\t\"Password\": " + "\"" + c.getPassword() + "\",\n");
				jsonRecords.add("\t\"Email\": " + "\"" + c.getEmail() + "\",\n");
				jsonRecords.add("}\n");
			}
			String[] toRec = new String[jsonRecords.size()];
			i=0;
			for (String string : jsonRecords) {
				toRec[i] = string;
				i++;
			}
			w.write(fileName, toRec);
			break;
		case YAML:
			System.out.println("YAML-export is not implemented yet.");
			break;
		case CSV:
			String[] csvRecords = new String[clients.size() + 1];
			csvRecords[0] = "���;����� ��������;����� �� �����;������\n";
			i = 1;
			for (Client c : clients){
				csvRecords[i] = c.getName() + ";" + c.getPassportId() + ";" + c.getMoney() + ";" + c.getPassword() + ";" + c.getEmail() + "\n";
				i++;
			}
			w.write(fileName, csvRecords);
			break;
		case XML:
			String[] xmlRecords = new String[clients.size()];
			ArrayList<String> data = new ArrayList<String>();
			
			data.add("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n");
			data.add("<clients>\n");
			i=0;
			for (Client c : clients) {
				data.add("\t<client>\n");
				xmlRecords[i] ="\t\t<client_pid>\n"+"\t\t\t"+c.getPassportId()+"\n"
							+"\t\t</client_pid>\n"
							+"\t\t<client_name>\n"
							+"\t\t\t"+c.getName()+"\n"
							+"\t\t</client_name>\n"
							+"\t\t<client_money>\n"
							+"\t\t\t"+c.getMoney()+"\n"
							+"\t\t</client_money>\n"
							+"\t\t<client_password>\n"
							+"\t\t\t"+c.getPassword()+"\n"
							+"\t\t</client_password>\n"
							+"\t\t<client_email>\n"
							+"\t\t\t"+c.getEmail()+"\n"
							+"\t\t</client_email>\n";
				data.add(xmlRecords[i]);
				data.add("\t</client>\n");
				System.out.println("added: "+xmlRecords[i]);
				i++;
			}
			data.add("</clients>");
			
			String[] xmlToRec = new String[data.size()];
			i=0;
			for (String string : data) {
				xmlToRec[i] = string;
				i++;
			}
			w.write(fileName, xmlToRec);
			break;
		default:
			break;
		}
	}
	/**
	 * Exports Orders to file
	 * @param fileName
	 * @param wt writer type
	 */
	public static void exportOrdersToFile(String fileName, WriterType wt) {
		Writer w = getWriter(wt);
		int i = 0;
		switch (wt) {
		case TXT:
			String[] records = new String[orders.size() + 1];
			records[0] = "ID\t����� ��������\tID ������\t�� ����� ���������� ����\t��������� ������\n";
			i = 1;
			for (Order o : orders) {
				records[i] = o.toString("to file") + "\n";
				i++;
			}
			w.write(fileName, records);
			break;
		case JSON:
			ArrayList<String> jsonRecords = new ArrayList<String>();
			for (Order o : orders) {
				jsonRecords.add("{\n");
				jsonRecords.add("\t\"Order ID\": " + "\"" + o.getId() + "\",\n");
				jsonRecords.add("\t\"Client ID\": " + "\"" + o.getClient().getPassportId() + "\",\n");
				jsonRecords.add("\t\"Car ID\": " + "\"" + o.getCar().getId() + "\",\n");
				jsonRecords.add("\t\"For days\": " + "\"" + o.getOrderCreated() + "\",\n");
				jsonRecords.add("\t\"State\": " + "\"" + o.getState() + "\",\n");
				jsonRecords.add("\t\"Reject reason\": " + "\"" + o.getRejectReason() + "\",\n");
				jsonRecords.add("\t\"Manager name\": " + "\"" + o.getManager() + "\",\n");
				jsonRecords.add("\t\"Order expires\": " + "\"" + o.getOrderExpires() + "\",\n");
//				jsonRecords.add("\t\"Reject reason\": " + "\"" + o.getRejectReason() + "\",\n");
				jsonRecords.add("}\n");
			}
			String[] toRec = new String[jsonRecords.size()];
			i=0;
			for (String string : jsonRecords) {
				toRec[i] = string;
				i++;
			}
			w.write(fileName, toRec);
			break;
		case CSV:
			String[] csvRecords = new String[orders.size() + 1];
			csvRecords[0] = "id;����� ��������;ID ������;�� ����� ���������� ����;��������� ������\n";
			i = 1;
			for (Order o : orders) {
				csvRecords[i] = o.getId() + ";" + o.getClient().getPassportId() + ";" + o.getCar().getId() + ";" + o.getOrderCreated() + ";" + o.getState() + "\n"; 
				i++;
			}
			w.write(fileName, csvRecords);
			break;
		case XML:
			ArrayList<String> data = new ArrayList<String>();
			data.add("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n");
			data.add("<orders>\n");
			i=0;
			for (Order c : orders) {
				data.add("\t<order>\n");
				data.add("\t\t<order_id>\n"+"\t\t\t"+c.getId()+"\n"
							+"\t\t</order_id>\n"
							+"\t\t<client_pid>\n"
							+"\t\t\t"+c.getClient()+"\n"
							+"\t\t</client_pid>\n"
							+"\t\t<car_id>\n"
							+"\t\t\t"+c.getId()+"\n"
							+"\t\t</car_id>\n"
							+"\t\t<manager_name>\n"
							+"\t\t\t"+c.getManager()+"\n"
							+"\t\t</manager_name>\n"
							+"\t\t<order_state>\n"
							+"\t\t\t"+c.getState()+"\n"
							+"\t\t</order_state>\n"
							+"\t\t<order_expires>\n"
							+"\t\t\t"+c.getOrderExpires()+"\n"
							+"\t\t</order_expires>\n"
							+"\t\t<order_created>\n"
							+"\t\t\t"+c.getOrderCreated()+"\n"
							+"\t\t</order_created>\n"
							+"\t\t<order_reject_reason>\n"
							+"\t\t\t"+c.getRejectReason()+"\n"
							+"\t\t</order_reject_reason>\n"
				);
				data.add("\t</order>\n");
				// System.out.println("added: "+xmlRecords[i]);
				i++;
			}
			data.add("</orders>");
			
			String[] xmlToRec = new String[data.size()];
			i=0;
			for (String string : data) {
				xmlToRec[i] = string;
				i++;
			}
			w.write(fileName, xmlToRec);
			break;
		default:
			break;
		}
	}	
	
//	protected static int f(String regex, String text) {
//	    Matcher m = Pattern.compile(regex).matcher(text);
//
//	    int count = 0;
//	    while (m.find()) {
//	      count++;
//	    }
//	    return count;
//	  }
	@Deprecated
	public static void importBaseFromFile(String basePath, WriterType wt) throws FileNotFoundException, IllegalArgumentException{
		switch (wt){
		case TXT:	
			try {
				importClientsFromFile(basePath + "clients.txt", wt);
				importCarsFromFile(basePath + "cars.txt", wt);
				importOrdersFromFile(basePath + "orders.txt", wt);
			} catch (Exception e) {
				e.printStackTrace();
			}
			break;
		case CSV:
			try {
				importClientsFromFile(basePath + "clients.csv", wt);
				importCarsFromFile(basePath + "cars.csv", wt);
				importOrdersFromFile(basePath + "orders.csv", wt);
			} catch (Exception e) {
				e.printStackTrace();
			}
			break;
		case JSON:
			try {
				importClientsFromFile(basePath + "clients.json", wt);
				importCarsFromFile(basePath + "cars.json", wt);
				importOrdersFromFile(basePath + "orders.json", wt);
			} catch (Exception e) {
				e.printStackTrace();
			}
		default:
			break;
		}
		
	}
	
	//	protected static int f(String regex, String text) {
	//	    Matcher m = Pattern.compile(regex).matcher(text);
	//
	//	    int count = 0;
	//	    while (m.find()) {
	//	      count++;
	//	    }
	//	    return count;
	//	  }
		/**
		 * Exports all entities to a different files
		 */
		public static void exportBaseToFile(String basePath, WriterType wt) throws FileNotFoundException, IllegalArgumentException{
			
			switch(wt){
			
			case TXT:		
				try {
					exportClientsToFile(basePath + "clients.txt", wt);
					exportCarsToFile(basePath + "cars.txt", wt);
					exportOrdersToFile(basePath + "orders.txt", wt);
				} catch (Exception e) {
					System.out.println(e.getMessage());
					e.printStackTrace();
				}
				break;
			case JSON:
				try {
					exportClientsToFile(basePath + "clients.json", wt);
					exportCarsToFile(basePath + "cars.json", wt);
					exportOrdersToFile(basePath + "orders.json", wt);
				} catch (Exception e) {
					System.out.println(e.getMessage());
					e.printStackTrace();
				}
				break;
			case CSV:
				try {
					exportClientsToFile(basePath + "clients.csv", wt);
					exportCarsToFile(basePath + "cars.csv", wt);
					exportOrdersToFile(basePath + "orders.csv", wt);
				} catch (Exception e) {
					System.out.println(e.getMessage());
					e.printStackTrace();
				}
			default:
				break;
			}
		}
		@Deprecated
	static void importClientsFromFile(String fileName, WriterType wt) throws FileNotFoundException, IllegalArgumentException, ClientException{
		Writer w = getWriter(wt);
		ArrayList<String> toParse = w.read(fileName);
		ArrayList<String[]> splitted = new ArrayList<String[]>();
		switch (wt) {
		case TXT:
			 splitted = Parsers.parseTxt(toParse);
			try {
				for (String[] strings : splitted) {
					create(strings[0], strings[1], Float.valueOf(strings[2]), strings[3], strings[4]);
					//clients.get(clients.size() - 1).setPassword(strings[3]);
				}
			} catch (IllegalArgumentException e) {
				System.out.println("���� � ��������� ���������!");
			}
			break;
		
		case CSV:
			splitted = Parsers.parseCsv(toParse);
			try {
				for (String[] strings : splitted) {
					create(strings[0], strings[1], Float.valueOf(strings[2]), strings[3], strings[4]);
					//clients.get(clients.size() - 1).setPassword(strings[3]);
				}
			} catch (IllegalArgumentException e) {
				System.out.println("���� � ��������� ���������!");
			}
			break;
		case JSON:
			splitted = Parsers.parseJson(toParse);
			try {
				for (String[] strings : splitted) {
					create(strings[1], strings[3], Float.valueOf(strings[5]), strings[7], strings[9]);
					//clients.get(clients.size() - 1).setPassword(strings[7]);
				}
			} catch (IllegalArgumentException e) {
				System.out.println("���� � ��������� ���������!");
			}
			break;
		case XML:
			XMLInputFactory factory = XMLInputFactory.newInstance();
			XMLStreamReader r = null;
			FileReader xml = null;
			String[] params = new String[5];
//			ArrayList<String[]> listParams = new ArrayList<String[]>(); 
			try {
				xml = new FileReader(fileName);
				r = factory.createXMLStreamReader(xml);
			} catch (XMLStreamException e) {
				e.printStackTrace();
			}
			try {
			      int event = r.getEventType();
			      String tmp = null;
			      while (true) {
			            switch (event) {
			            case XMLStreamConstants.START_DOCUMENT:
//			                  System.out.println("Start Document.");
			                  break;
			            case XMLStreamConstants.START_ELEMENT:
//			                  System.out.println("Start Element: " + r.getName());
			                  tmp = r.getLocalName();
//			                  for(int i = 0, n = r.getAttributeCount(); i < n; ++i)
//			                        System.out.println("Attribute: " + r.getAttributeName(i) 
//			                              + "=" + r.getAttributeValue(i));
			                  break;
			            case XMLStreamConstants.CHARACTERS:
			                  if (r.isWhiteSpace())
			                        break;
			                  
			                  switch(XmlVal.valueOf(tmp.toUpperCase())){
			                  case CLIENT_PID:
			                	  params[0] = r.getText().replace("\t", "");
			                	  params[0] = params[0].replace("\n", "");
//			                	  System.out.println(params[0]);
			                	  break;
			                  case CLIENT_NAME:
			                	  params[1] = r.getText().replace("\t", "");
			                	  params[1] = params[1].replace("\n", "");
//			                	  System.out.println(params[1]);
			                	  break;
			                  case CLIENT_MONEY:
			                	  params[2] = r.getText().replace("\t", "");
			                	  params[2] = params[2].replace("\n", "");
//			                	  System.out.println(params[2]);
			                	  break;
			                  case CLIENT_PASSWORD:
			                	  params[3] = r.getText().replace("\t", "");
			                	  params[3] = params[3].replace("\n", "");
//			                	  System.out.println(params[3]);
			                	  break;
			                  case CLIENT_EMAIL:
			                	  params[4] = r.getText().replace("\t", "");
			                	  params[4] = params[4].replace("\n", "");
//			                	  System.out.println(params[4]);
			                	  create(params[1], params[0], Float.valueOf(params[2]), params[3], params[4]);
			                	  break;
			                  default:
			                	throw new ClientException("xml file is corrupted!");
			                  }
			                  break;
			            case XMLStreamConstants.END_ELEMENT:
//			                  System.out.println("End Element:" + r.getName());
			                  break;
			            case XMLStreamConstants.END_DOCUMENT:
//			                  System.out.println("End Document.");
			                  break;
			            }

			            try {
							if (!r.hasNext())
							      break;
							event = r.next();
						} catch (XMLStreamException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						
			      }
			} finally {
			      try {
					r.close();
				} catch (XMLStreamException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			break;
		default:
			break;
		}
	}
	@Deprecated
	static void importCarsFromFile(String fileName, WriterType wt) throws FileNotFoundException, IllegalArgumentException {
		Writer w = getWriter(wt);
		ArrayList<String> toParse = w.read(fileName);
		ArrayList<String[]> splitted = new ArrayList<String[]>();
		switch (wt) {
		case TXT:
			splitted = Parsers.parseTxt(toParse);
			//carId, carName, price, type, damages, rentBy, rentFor
			try {
				for (String[] string : splitted) {
					Management.create(string[1], Double.parseDouble(string[2]),	string[3]);
					cars.get(cars.size() - 1).setCarId(Long.valueOf(string[0]));
					cars.get(cars.size() - 1).setDamages(Damages.valueOf(string[4]));
					cars.get(cars.size() - 1).setRentBy(Management.getClientByPID(string[5]));
					// cars.get(cars.size() - 1).setRentFor(Integer.valueOf(string[6]));
				}
			} catch (Exception e) {
				System.out.println("���� � �������� ���������!");
				e.getCause();
				e.printStackTrace();
			}
			break;
			
		case CSV:
			splitted = Parsers.parseCsv(toParse);
			//carId, carName, price, type, damages, rentBy, rentFor
			try {
				for (String[] string : splitted) {
					Management.create(string[1], Double.parseDouble(string[2]),	string[3]);
					cars.get(cars.size() - 1).setCarId(Long.valueOf(string[0]));
					cars.get(cars.size() - 1).setDamages(Damages.valueOf(string[4]));
					cars.get(cars.size() - 1).setRentBy(Management.getClientByPID(string[5]));
					// cars.get(cars.size() - 1).setRentFor(Integer.valueOf(string[6]));
				}
			} catch (Exception e) {
				System.out.println("���� � �������� ���������!");
				e.getCause();
				e.printStackTrace();
			}
			break;
		case JSON:
			splitted = Parsers.parseJson(toParse);
			//carId, carName, price, type, damages, rentBy, rentFor
			try {
				for (String[] string : splitted) {
					Management.create(string[3], Double.parseDouble(string[5]),	string[7]);
					cars.get(cars.size() - 1).setCarId(Long.valueOf(string[1]));
					cars.get(cars.size() - 1).setDamages(Damages.valueOf(string[9]));
					cars.get(cars.size() - 1).setRentBy(Management.getClientByPID(string[11]));
					//cars.get(cars.size() - 1).setRentFor(Integer.valueOf(string[13]));
				}
			} catch (Exception e) {
				System.out.println("���� � �������� ���������!");
				e.getCause();
				e.printStackTrace();
			}
			break;

		default:

			break;
		}
	}
	@Deprecated
	static void importOrdersFromFile(String fileName, WriterType wt) throws FileNotFoundException, IllegalArgumentException{
		Writer w = getWriter(wt);
		ArrayList<String> toParse = w.read(fileName);
		ArrayList<String[]> splitted = new ArrayList<String[]>();
		
		switch (wt) {
		case TXT:
//			splitted = Parsers.parseTxt(toParse);
//			
//			try {
//				for (String[] strings : splitted) {
//					create(getClientByPID(strings[1]), getCarById(Long.valueOf(strings[2])), strings[3]);
//					orders.get(orders.size() - 1).setState(OrderState.valueOf(strings[4]));
//					orders.get(orders.size() - 1).setId(Long.valueOf(strings[0]));
//				}
//			} catch (IllegalArgumentException e) {
//				System.out.println("���� ������ ���������!");
//				e.printStackTrace();
//			}
			break;
		case CSV:
//			splitted = Parsers.parseCsv(toParse);
//			try {
//				for (String[] strings : splitted) {
//					create(getClientByPID(strings[1]), getCarById(Long.valueOf(strings[2])), strings[3]);
//					orders.get(orders.size() - 1).setState(OrderState.valueOf(strings[4]));
//					orders.get(orders.size() - 1).setId(Long.valueOf(strings[0]));
//					orders.get(orders.size() - 1).setManager(new Manager(strings[6], null));
//					orders.get(orders.size() - 1).setOrderExpires(strings[7]);
//				}
//			} catch (IllegalArgumentException e) {
//				System.out.println("���� ������ ���������!");
//				e.printStackTrace();
//			}
			break;
		case JSON:
			splitted = Parsers.parseJson(toParse);
			try {
				for (String[] strings : splitted) {
					if (getManagerByName(strings[13])!= null){
						create(getManagerByName(strings[13]), getClientByPID(strings[3]), getCarById(Long.valueOf(strings[5])), strings[7]);	
					}else {
						create(strings[13], "defpass");
						create(getManagerByName(strings[13]), getClientByPID(strings[3]), getCarById(Long.valueOf(strings[5])), strings[7]);
					}
					orders.get(orders.size() - 1).setState(OrderState.valueOf(strings[9]));
					orders.get(orders.size() - 1).setId(Long.valueOf(strings[1]));
					orders.get(orders.size() - 1).setOrderExpires(strings[15]);
					orders.get(orders.size() - 1).setRejectReason(strings[11]);
				}
			} catch (IllegalArgumentException e) {
				System.out.println("���� ������ ���������!");
				e.printStackTrace();
//			}catch (NoSuchManagerException e){
//				System.out.println("�������� �� ������!");
//				e.printStackTrace();
			}
			break;


		default:

			break;
		}
	}
	@Deprecated
	public static void importClientsFromList(ArrayList<Client> list){
		clients = list;
	}
	@Deprecated
	public static void importCarsFromList(ArrayList<Car> list){
		cars = list;
	}
	@Deprecated
	public static void importManagersFromList(ArrayList<Manager> list){
		managers = list;
	}
	@Deprecated
	public static void importOrdersFromList(ArrayList<Order> list){
		orders = list;
	}
	/**
	 * prints all clients (stored in memory!)
	 */
	public static void printClients(){
		if (clients.size() != 0) {
			for (Client c : clients) {
				System.out.println(c.toString() + " " + c.getName());
			}
		}else{
			System.out.println("There are no clients registered in the system.\n");
		}
	}
	/**
	 * prints all cars (stored in memory!)
	 */
	public static void printCars(){
		if (cars.size() != 0) {
			for (Car c : cars) {
				System.out.println(c.toString());
			}
		}else{
			System.out.println("There are no cars registered in the system.\n");
		}
	}
	/**
	 * prints all orders (stored in memory!)
	 */
	public static void printOrders(){
		if (orders.size() != 0) {
			for (Order o : orders) {
				System.out.println(o.toString());
			}
		}else{
			System.out.println("There are no orders registered in the system.\n");
		}
	}
	/**
	 * prints all managers (stored in memory!)
	 */
	public static void printManagers(){
		if (managers.size() != 0) {
			for (Manager m : managers) {
				System.out.println(m.toString());
			}
		}else{
			System.out.println("There are no managers registered in the system.\n");
		}
	}
	@Deprecated
	public static void printWholeBase(){
		System.out.println("\n]]]]]]]]]]]]]]] CLIENTS:\n");
		printClients();
		System.out.println("\n]]]]]]]]]]]]]]] CARS:\n");
		printCars();
		System.out.println("\n]]]]]]]]]]]]]]] ORDERS:\n");
		printOrders();
		System.out.println("\n]]]]]]]]]]]]]]] MANAGERS:\n");
		printManagers();
	}
	
	@Deprecated
	@SuppressWarnings("unchecked")
	public static ArrayList<Car> getCars() {
		return (ArrayList<Car>) cars.clone();
	}
	@Deprecated
	public Car getCarByModel(String model){
		for (Car c : cars) {
			if(c.getModel() == model){
				return c;
			}
		}
		return null;
	}
	@Deprecated
	public static Manager getManagerByName(String name){
		for (Manager m : managers){
			if (m.getName().equals(name)){
				return m;
			}
		}
		return null;
	}
	@Deprecated
	@SuppressWarnings("unchecked")
	public static ArrayList<Client> getClients() {
		return (ArrayList<Client>) clients.clone();
	}
	@Deprecated
	@SuppressWarnings("unchecked")
	public static ArrayList<Order> getOrders() {
		return (ArrayList<Order>) orders.clone();
	}
	@Deprecated
	@SuppressWarnings("unchecked")
	public static ArrayList<Manager> getManagers() {
		return (ArrayList<Manager>) managers.clone();
	}
	@Deprecated
	public static Order getOrderById(long id) {
		for (Order o : orders) {
			if (o.getId() == id) {
				return o;
			}
		}
		return null;
	}
	@Deprecated
	public ArrayList<Order> getOrdersByClient(Client c) {
		ArrayList<Order> res = new ArrayList<Order>();
		for (Order o : orders) {
			if (o.getClient() == c) {
				res.add(o);
			}
		}
		return res;
	}

	/**
	 * removes a car from a list of cars in memory
	 * @param a1
	 */
	public void removeCar(Car a1) {
		cars.remove(a1);
	}

	/**
	 * removes a car from a list of client in memory
	 * @param a1
	 */
	public void removeClient(Client c1) {
		clients.remove(c1);
	}

	/**
	 * This method allows to rent a car for the client.
	 * This method returns an Order, managed by manager.
	 * 
	 * 
	 * 
	 * @param m
	 * @param a1
	 * @param c1
	 * @param creationDate
	 * @return
	 */
	public static Order rentCar(Manager m, Car a1, Client c1, String creationDate) {
		if (a1 == null) {
			try {
				throw new NoSuchCarException();
			} catch (NoSuchCarException e) {
				System.out.println("There's no such car!\n");
				return null;
			}
		}
		if (c1 == null) {
			try {
				throw new NoSuchClientException();
			} catch (NoSuchClientException e) {
				System.out.println("There's no such client!\n");
				return null;
			}
		}
		if ((a1.getRentBy() == null)) {
			a1.setRentBy(c1);
			//orders.add(new Order(m, c1, a1, creationDate));
			return new Order(m, c1, a1, creationDate);
		} else {
			return null;
		}
			
	}

	/**
	 * Not yet realised
	 * @param a1
	 * @return
	 */
	public boolean returnCar(Car a1) {
		if (a1.getRentBy() != null) {
			a1.setRentBy(null);
			return true;
		} else
			return false;
	}

	@Deprecated
	public ArrayList<Car> getCarsForClient(Client c1) {
		ArrayList<Car> result = new ArrayList<Car>();
		for (Car aCar : getCars()) {
			if ((aCar.getRentBy() != null) && aCar.getRentBy().getName().equals(c1.getName())) {
				result.add(aCar);
			}
		}
		return result;
	}
	
	public String getPassportId(){
		return null;
	}
	public String getName(){
		return null;
	}
	public float getMoney(){
		return 0;
	}
	public String getPassword(){
		return null;
	}
	public String getEmail(){
		return null;
	}
	public long getId(){
		return 0;
	}
	public Client getRentBy(){
		return null;
	}
	public Client getClient(){
		return null;
	}
	public String getModel(){
		return null;
	}
	public double getPrice(){
		return 0;
	}
	public Car getCar(){
		return null;
	}
	public CarType getCarType(){
		return null;
	}
	public Damages getDamages(){
		return null;
	}
	public Manager getManager(){
		return null;
	}
	public OrderState getState(){
		return null;
	}
	public String getOrderExpires(){
		return null;
	}
	public String getOrderCreated(){
		return null;
	}
	public String getRejectReason(){
		return null;
	}
	
	
	
	
	
}